package com.kenliang.netty.rpc.netty;

import com.kenliang.netty.rpc.config.RpcSystemConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoop;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;

import java.net.InetSocketAddress;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

/**
 * @author KenLiang
 * @description:发送请求任务类
 * @date Created in 5:50 PM 2019/3/21.
 */
@Slf4j
public class MessageSendInitializeTask implements Callable<Boolean> {


    private InetSocketAddress inetSocketAddress;
//    todo  这个线程数有什么用吗？
    private NioEventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(2);

    public MessageSendInitializeTask(InetSocketAddress inetSocketAddress){
        this.inetSocketAddress = inetSocketAddress;
    }

    @Override
    public Boolean call() {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(this.nioEventLoopGroup)
                .channel(NioSocketChannel.class)
                .remoteAddress(this.inetSocketAddress)
                .option(ChannelOption.SO_KEEPALIVE,true)
                .handler(new MessageSendChannelInitializer());

        ChannelFuture channelFuture  = bootstrap.connect();
        channelFuture.addListener((ChannelFutureListener) future -> {
            if(future.isSuccess()) {
                log.info("------channelFuture --listener--connect-successs--------");

                MessageSendHandler messageSendHandler = future.channel().pipeline().get(MessageSendHandler.class);
                RpcClientLoader.getInstance().setMessageSendHandler(messageSendHandler);
            }else{
                log.info("---------reconnnect--------");

                //重连
                this.nioEventLoopGroup.schedule((()->{
                    log.info("server is down,start to reconnecting ,server address {}:{}", this.inetSocketAddress.getHostString(),this.inetSocketAddress.getPort());
                    this.call();
                }), RpcSystemConfig.CLIENT_RECONNECT_DELAY, TimeUnit.SECONDS);
            }
        });
        return Boolean.TRUE;
    }
}
